package org.littlesun.management.ui.test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;

import org.apache.commons.lang3.builder.CompareToBuilder;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;
import org.littlesun.management.jface.fieldassist.AutoCompleteField;
import org.littlesun.management.jface.fieldassist.ContentProposalProvider;
import org.littlesun.management.model.child.Child;
import org.littlesun.management.model.child.Child.SimpleChild;
import org.littlesun.management.service.ChildService;

public class MainForm {

	protected ChildService childService = new ChildService();

	protected Shell shell;
	private Combo nameCombo;
	private ComboViewer nameComboViewer;
	private Text medicalNoText;
	private Label medicalNoLabbel;

	/**
	 * Launch the application.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		MainForm window = new MainForm();
		window.open();
	}

	/**
	 * Open the window.
	 */
	public void open() {
		Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		shell = new Shell();
		shell.setSize(550, 422);
		shell.setText("\u5152\u7AE5\u8CC7\u6599");
		shell.setLayout(new FormLayout());
		
		Label nameLabel = new Label(shell, SWT.NONE);
		nameLabel.setFont(SWTResourceManager.getFont("Microsoft JhengHei UI", 12, SWT.NORMAL));
		FormData fd_nameLabel = new FormData();
		fd_nameLabel.top = new FormAttachment(0, 13);
		fd_nameLabel.right = new FormAttachment(100, -460);
		nameLabel.setLayoutData(fd_nameLabel);
		nameLabel.setText("\u5152\u7AE5\u59D3\u540D");
		
		medicalNoLabbel = new Label(shell, SWT.NONE);
		medicalNoLabbel.setText("\u75C5\u6B77\u865F\u78BC");
		medicalNoLabbel.setFont(SWTResourceManager.getFont("Microsoft JhengHei UI", 12, SWT.NORMAL));
		FormData fd_medicalNoLabbel = new FormData();
		fd_medicalNoLabbel.top = new FormAttachment(nameLabel, 0, SWT.TOP);
		medicalNoLabbel.setLayoutData(fd_medicalNoLabbel);
		
		nameCombo = new Combo(shell, SWT.BORDER);
		nameCombo.setFont(SWTResourceManager.getFont("Microsoft JhengHei UI", 12, SWT.NORMAL));
		FormData fd_nameText = new FormData();
		fd_nameText.right = new FormAttachment(nameLabel, 158, SWT.RIGHT);
		fd_nameText.top = new FormAttachment(0, 10);
		fd_nameText.left = new FormAttachment(nameLabel, 6);
		nameCombo.setLayoutData(fd_nameText);
		
		nameComboViewer = new ComboViewer(nameCombo);
		
		medicalNoText = new Text(shell, SWT.BORDER);
		fd_medicalNoLabbel.right = new FormAttachment(medicalNoText, -6);
		medicalNoText.setFont(SWTResourceManager.getFont("Microsoft JhengHei UI", 12, SWT.NORMAL));
		FormData fd_medicalNoText = new FormData();
		fd_medicalNoText.top = new FormAttachment(0, 10);
		fd_medicalNoText.left = new FormAttachment(nameCombo, 123);
		fd_medicalNoText.right = new FormAttachment(100, -27);
		medicalNoText.setLayoutData(fd_medicalNoText);
		medicalNoText.setEditable(false);

		List<Child> children = childService.getChildren();
				
		nameComboViewer.setContentProvider(new ArrayContentProvider());
		nameComboViewer.setLabelProvider(new LabelProvider() {
            public String getText(Object element) {
            	Child child = (Child) element;
                return child.getName() + "-" + child.getMedicalNo();
          }
		});
		nameComboViewer.setInput(children);
		
		List<String> childrenAsString = new ArrayList<String>();
		for(Child child : children) {
			childrenAsString.add(child.getName() + "-" + child.getMedicalNo());
		}
//		new AutoCompleteField(nameCombo, 
//				ContentProposalProvider.contains(childrenAsString.toArray(new String[] {})), 
//				new ComboContentAdapter());
	}

	public static class MyContentProvider implements IStructuredContentProvider {

		public Object[] getElements(Object inputElement) {
			return (Object[]) inputElement;
		}

		public void dispose() {
		}

		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		}

	}

	public static class MyComparator extends ViewerComparator {
		private int historyPropertySize = 3;
		private List<PropertyIndexAndDirection> propertyIndexes = new LinkedList<PropertyIndexAndDirection>();

		public MyComparator() {
			addPropertyIndex(0, -1);
		}

		public int getDirection() {
			return propertyIndexes.get(0).getDirection();
		}

		void addPropertyIndex(int column) {
			PropertyIndexAndDirection propertyIndex = propertyIndexes.get(0);
			if (column == propertyIndex.column) {
				propertyIndex.direction = -1 * propertyIndex.direction;
			} else {
				addPropertyIndex(column, -1);
			}
		}
		
		void addPropertyIndex(int column, int direction) {
			for(Iterator<PropertyIndexAndDirection> it = this.propertyIndexes.iterator(); it.hasNext(); ) {
				if (it.next().getColumn() == column) {
					it.remove();
				}
			}
			propertyIndexes.add(0, new PropertyIndexAndDirection(column, direction));
			if (propertyIndexes.size() > historyPropertySize) {
				propertyIndexes.remove(propertyIndexes.size() - 1);
			}
		}

//		public int getDirection() {
//			return direction == 1 ? SWT.DOWN : SWT.UP;
//		}

		public void setColumn(int column) {
			addPropertyIndex(column);
		}

		@Override
		public int compare(Viewer viewer, Object e1, Object e2) {
			Child p1 = (Child) e1;
			Child p2 = (Child) e2;
			CompareToBuilder compareToBuilder = new CompareToBuilder();
			for(PropertyIndexAndDirection proeprtyIndex : propertyIndexes) {
				Object value1 = getValueByIndex(p1, proeprtyIndex.getColumn());
				Object value2 = getValueByIndex(p2, proeprtyIndex.getColumn());
				if (proeprtyIndex.direction >= 0) {
					compareToBuilder = compareToBuilder.append(value1, value2);
				}
				else {
					compareToBuilder = compareToBuilder.append(value2, value1);
				}
			}
			return compareToBuilder.toComparison();
		}

		public Object getValueByIndex(Child child, int column) {
			switch (column) {
			case 0:
				return child.getName();
			case 1:
				return child.getMedicalNo();
			case 2:
				return child.getBirthday();
			case 3:
				return child.getIdNo();
			default:
				return 0;
			}
		}
	}
	
	@Data
	@AllArgsConstructor
	public static class PropertyIndexAndDirection {
		private int column;
		private int direction;
	}
}
